package com.tianyu.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.tianyu.common.AppConstants;
import com.tianyu.common.RSAEncryptionTool;
import com.tianyu.model.dto.AccessInfo;
import com.tianyu.model.entity.ThirdCompanyAccessChannel;
import com.tianyu.model.enums.ThirdMethodEnum;
import com.tianyu.model.ro.Ro2;
import com.tianyu.model.ro.ServiceRo;
import com.tianyu.service.other.ApiService;
import com.tianyu.service.base.ThirdCompanyAccessChannelService;
import com.tianyu.service.base.api.CommandReceive;
import com.tianyu.service.cache.DataCacheService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.TreeMap;


/**********************************
 * @author swyan
 * @description ApiController.java
 * @date 2024/7/10 - 16:31
 **********************************/

@Slf4j
@RestController
@RequestMapping("/api/v1.0")
public class ApiController {

    @Resource
    private ApiService apiService;

    @Resource
    private AppConstants appConstants;

    @Resource
    private ThirdCompanyAccessChannelService thirdCompanyAccessChannelService;

    @Resource
    private DataCacheService dataCacheService;

    @Resource
    private CommandReceive commandReceive;

    @PostMapping("/third-1/callback/{companyCode}")
    private Ro2<?> getQiyunSiteStateMap(@PathVariable String companyCode,
                                        @RequestHeader("method") Map<String, String> headerMap,
                                        @RequestHeader("method") String method,
                                        @RequestBody TreeMap<String, Object> body
    ) {
        log.info("接收到回调companyCode: {}, method: {}, Headers: {}, body: {}",
                companyCode,
                method,
                JSON.toJSONString(headerMap),
                JSON.toJSONString(body));
        final String privatePemByThirdId = dataCacheService.getPrivatePemByThirdId(companyCode);
        if (privatePemByThirdId == null) {
            return Ro2.error("项目码[" + companyCode + "]密钥不存在");
        }
        final ServiceRo<?> validationSign = apiService.validationSign(headerMap, body, privatePemByThirdId);
        if (appConstants.isThird01ValidRequest() && !validationSign.getResult()) {
            return Ro2.error(validationSign.getMessage());
        }
        String authorization = headerMap.get("authorization");
        final AccessInfo accessInfo = apiService.getAccessInfo(authorization);
        final JSONObject params = JSONObject.from(body);
        if (accessInfo != null) {
            log.info(accessInfo.toString());
            final String appKey = accessInfo.getAppKey();
            params.put("appKey", appKey);
        }
        params.put("companyCode", companyCode);
        final ThirdMethodEnum methodEnum = ThirdMethodEnum.findByMethod(method);
        ServiceRo<?> serviceRo = switch (methodEnum) {
            case DOCK_LEDGER_INFO -> commandReceive.dockLedgerInfo(params);
            case AIRCRAFT_LEDGER_INFO -> commandReceive.aircraftLedgerInfo(params);
            case FLIGHT_LINES -> commandReceive.flightLines(params);
            case DOCK_CAMERA_LIVE -> commandReceive.dockCameraLive(params);
            case AIRCRAFT_CAMERA_LIVE -> commandReceive.aircraftCameraLive(params);
            case TAKEOFF_TO_POINT -> commandReceive.takeoffToPoint(params);
            case FLY_TO_POINT -> commandReceive.flyToPoint(params);
            case FLIGHT_TASK -> commandReceive.flyTask(params);
            case HOVER -> commandReceive.flyPause(params);
            case CONTINUE_FLIGHT -> commandReceive.flyRecovery(params);
            case RETURN_HOME -> commandReceive.returnHome(params);
            case CAMERA_RESET -> commandReceive.gimbalReset(params);
            case CAMERA_ZOOM_FOCAL -> commandReceive.cameraFocalLengthSet(params);
            case CAMERA_LENS -> commandReceive.liveLensChange(params);
            case CAMERA_QUALITY -> commandReceive.liveSetQuality(params);
            case CAMERA_AIM -> commandReceive.cameraAim(params);
            case MANUAL_JOYSTICK -> commandReceive.droneControl(params);
            default -> ServiceRo.resultFailed("无效调用方法[" + method + "]");
        };
        if (!serviceRo.getResult()) {
            return Ro2.error().failureResult(serviceRo.getMessage());
        }
        return Ro2.success(serviceRo.getData());
    }


    @PostMapping("/third-1/rsa-make/{companyCode}")
    private Ro2<?> buildRsa(@PathVariable String companyCode) {
        final ThirdCompanyAccessChannel one = thirdCompanyAccessChannelService.selectByThirdId(companyCode);
        if (one == null) {
            return Ro2.error("第三方编码不存在");
        }
        final JSONObject accessChannel = one.getAccessChannel();
        if (accessChannel != null) {
            final String rsaPublic = accessChannel.getString("rsaPublic");
            final String rsaPrivate = accessChannel.getString("rsaPrivate");
            if (rsaPublic != null && rsaPrivate != null) {
                return Ro2.success(JSONObject.of("rsaPublic", rsaPublic, "rsaPrivate", rsaPrivate));
            }
        }
        final JSONObject data = RSAEncryptionTool.rsaStringBuild();
        if (accessChannel == null) {
            one.setAccessChannel(JSONObject.from(data).fluentPut("accessType", 1));
        } else {
            accessChannel.putAll(JSONObject.from(data).fluentPut("accessType", 1));
        }
        thirdCompanyAccessChannelService.updateById(one);
        return Ro2.success(data);
    }

    @PostMapping("/third-1/generate")
    private Ro2<?> thirdGenerate(@RequestBody JSONObject params) {
        final String companyCode = params.getString("companyCode");
        final Integer ykCompanyId = params.getInteger("ykCompanyId");
        final String remark = params.getString("remark");
        final ThirdCompanyAccessChannel one = thirdCompanyAccessChannelService.selectByThirdId(companyCode);
        if (one != null) {
            return Ro2.error("第三方编码已存在");
        }
        final JSONObject accessChannel = RSAEncryptionTool.rsaStringBuild();
        accessChannel.put("accessType", 1);
        final ServiceRo<?> serviceRo = thirdCompanyAccessChannelService.insert(ThirdCompanyAccessChannel.builder()
                .thirdId(companyCode)
                .ykCompanyId(ykCompanyId)
                .remark(remark)
                .accessChannel(accessChannel).build());
        if (!serviceRo.getResult()) {
            return Ro2.success().failureResult("生成失败");
        }
        return Ro2.success(accessChannel);
    }
}
